home *** CD-ROM | disk | FTP | other *** search
- /* OS- and machine-dependent stuff for IBM-PC running MS-DOS */
- #include <stdio.h>
- #include <sgtty.h>
- #include "global.h"
- #include "mbuf.h"
- #include "internet.h"
- #include "iface.h"
- #include "cmdparse.h"
-
- /* This flag is set by setirq() if IRQ 8-15 is used, indicating
- * that the machine is a PC/AT with a second 8259 interrupt controller.
- * If this flag is set, the interrupt return code in pcgen.asm will
- * send an End of Interrupt command to the second 8259 as well as the
- * first.
- */
- char isat;
-
- /* Interface list header */
- struct interface *ifaces;
-
- /* Aztec memory allocation control */
- int _STKLOW = 0; /* Stack above heap */
- int _STKSIZ = 16384/16; /* 16K stack -- overridden in grabcore */
- int _HEAPSIZ = 4096/16; /* Isn't really used */
- int _STKRED = 4096; /* Stack red zone in bytes -- this really matters */
-
- char ttbuf[BUFSIZ];
-
- /* Called at startup time to set up console I/O, memory heap */
- ioinit()
- {
- struct sgttyb ttybuf;
- unsigned grabcore();
-
- /* Save these two file table entries for something more useful */
- fclose(stdaux);
- fclose(stdprt);
-
- /* Interrupts use a special stack deep in data space.
- * Calls to sbrk() (invoked by malloc when it needs more memory
- * from the system) at interrupt time will fail because sbrk()
- * will think that the stack has overwritten the heap. So
- * grab all the memory we can now for the heap so that malloc
- * won't have to call sbrk and alloc_mbuf() won't fail unnecessarily
- * at interrupt time.
- */
- grabcore();
-
- setbuf(stdout,ttbuf);
-
- /* Put display in raw mode. Note that this breaks tab expansion,
- * so you need to run NANSI.SYS or equivalent.
- */
- ioctl(1,TIOCGETP,&ttybuf);
- ttybuf.sg_flags = RAW;
- ioctl(1,TIOCSETP,&ttybuf);
- }
- /* Called just before exiting to restore console state */
- iostop()
- {
- struct sgttyb ttybuf;
-
- setbuf(stdout,NULLCHAR);
- ioctl(1,TIOCGETP,&ttybuf);
- ttybuf.sg_flags &= ~RAW;
- ioctl(1,TIOCSETP,&ttybuf);
- while(ifaces != NULLIF){
- if(ifaces->stop != NULLFP)
- (*ifaces->stop)(ifaces);
- ifaces = ifaces->next;
- }
- }
- /* Spawn subshell */
- doshell(argc,argv)
- {
- char *command,*getenv();
- struct sgttyb ttybuf,ttysav;
- int ret;
-
- ioctl(1,TIOCGETP,&ttysav);
- ioctl(1,TIOCGETP,&ttybuf);
- ttybuf.sg_flags &= ~RAW;
- ioctl(1,TIOCSETP,&ttybuf);
-
- if((command = getenv("COMSPEC")) == NULLCHAR)
- command = "/COMMAND.COM";
- ret = fexecl(command,command,NULLCHAR);
- ioctl(1,TIOCSETP,&ttysav);
- if(ret == -1)
- return -1;
- else
- return wait();
- }
-
- /* checks the time then ticks and updates ISS */
- static short clockstart = 0;
- static short clkval = 0;
- void
- check_time()
- {
- int32 iss();
- short ntime;
-
- if(!clockstart){
- /* Executed only once */
- clkval = peekw(0x6c,0x40);
- clockstart = 1;
- return;
- }
- /* Read the low order word of the BIOS tick counter directly. The
- * INT 1Ah call isn't used because it stupidly clears the
- * "midnight passed" flag and we'd have to update the date ourselves.
- * (See Norton, p222).
- *
- * The PC's time-of-day handling is a real crock of shit. Why not a
- * nice simple long binary count from a fixed UTC epoch, as in UNIX??
- */
- ntime = peekw(0x6c,0x40);
- while(ntime != clkval){ /* Handle possibility of several missed ticks */
- clkval++;
- icmpclk(); /* Call this one before tick */
- tick();
- (void)iss();
- }
- }
- /* Read characters from the keyboard, translating them to "real" ASCII
- * If none are ready, return the -1 from kbraw()
- */
- int
- kbread()
- {
- int kbraw(),c;
-
- if((c = kbraw()) == 0){
- /* Lead-in to a special char */
- c = kbread();
- switch(c){
- case 3: /* NULL (bizzare!) */
- c = 0;
- break;
- case 68: /* F-10 key (used as command-mode escape) */
- c = -2;
- break;
- case 83: /* DEL key */
- c = 0x7f;
- break;
- default: /* Dunno what it is */
- c = -1;
- }
- }
- return c;
- }
- #define CTLZ 26
- /* Special version of aputc() (used by putchar and printf) that filters
- * out nasty characters that screw up the DDOS and ANSI terminal drivers
- */
- aputc(c,file)
- char c;
- FILE *file;
- {
- /* Nulls get displayed as spaces by ansi.sys (wrong)
- * ^Z's seem to hang the DoubleDos and DesqView screen drivers
- */
- if((c == '\0' || c == CTLZ) && file == stdout)
- return c;
- /* Do end-of-line translations */
- if(c == '\n')
- putc('\r',file);
- return putc(c,file);
- }
- /* Reset the CPU, reboot DOS */
- sysreset()
- {
- int16 regs[8]; /* Not really needed */
-
- farcall(0x0,0xffff,regs,regs);
- }
-
- /* Install hardware interrupt handler.
- * Takes IRQ numbers from 0-7 (0-15 on AT) and maps to actual 8086/286 vectors
- * Note that bus line IRQ2 maps to IRQ9 on the AT
- */
- setirq(irq,handler)
- unsigned irq;
- void (*handler)();
- {
- /* Set interrupt vector */
- if(irq < 8){
- setvect(8+irq,handler);
- } else if(irq < 16){
- isat = 1;
- setvect(0x70 + irq - 8,handler);
- } else {
- return -1;
- }
- return 0;
- }
- /* Return pointer to hardware interrupt handler.
- * Takes IRQ numbers from 0-7 (0-15 on AT) and maps to actual 8086/286 vectors
- */
- void
- (*getirq(irq))()
- unsigned int irq;
- {
- void (*getvect())();
-
- /* Set interrupt vector */
- if(irq < 8){
- return getvect(8+irq);
- } else if(irq < 16){
- return getvect(0x70 + irq - 8);
- } else {
- return NULLVFP;
- }
- }
- /* Disable hardware interrupt */
- maskoff(irq)
- unsigned irq;
- {
- if(irq < 8){
- setbit(0x21,(char)(1<<irq));
- } else if(irq < 16){
- irq -= 8;
- setbit(0xa1,(char)(1<<irq));
- } else {
- return -1;
- }
- return 0;
- }
- /* Enable hardware interrupt */
- maskon(irq)
- unsigned irq;
- {
- if(irq < 8){
- clrbit(0x21,(char)(1<<irq));
- } else if(irq < 16){
- irq -= 8;
- clrbit(0xa1,(char)(1<<irq));
- } else {
- return -1;
- }
- return 0;
- }
- /* Return 1 if specified interrupt is enabled, 0 if not, -1 if invalid */
- getmask(irq)
- unsigned irq;
- {
- if(irq < 8)
- return (inportb(0x21) & (1 << irq)) ? 0 : 1;
- else if(irq < 16){
- irq -= 8;
- return (inportb(0xa1) & (1 << irq)) ? 0 : 1;
- } else
- return -1;
- }
-